/**
*tagfolder
*Licensed under LGPL
*http://code.google.com/p/tagfolder
*chuanshenglu@gmail.com
*xrjieyee@gmail.com
*
*/

#include "TFServerTask.h"
#include <TFstd.h>
#include "TFServerBuffer.h"
#include <iostream>
//
TFServerTaskDispatcher* TFServerTaskDispatcher::instance=NULL;

//
TFServerTaskDispatcher::TFServerTaskDispatcher()
{
	TaskHandlers.clear();
}

//Delete those small objects;
//Fuck, its so inconveniont to not use boost::shared_ptr
TFServerTaskDispatcher::~TFServerTaskDispatcher()
{
	for ( std::map<long, TFServerTaskHandler*>::iterator itr=TaskHandlers.begin() ;
		itr!=TaskHandlers.end() ;
		itr++ )
	{
		if(itr->second!=NULL)
			delete itr->second;
	}
}
//Get a instance of the singleton object;
TFServerTaskDispatcher*  TFServerTaskDispatcher::GetInstance()
{
	if(instance==NULL)
	{
		instance=new TFServerTaskDispatcher();
	}
	return instance;
}

//Dispatch message , calling the handler;
void TFServerTaskDispatcher::Dispatch(TFMessage& msg,TFDuplexChannel & channel)
{
	std::map<long, TFServerTaskHandler*>::iterator itr=TaskHandlers.find(msg.ID);
	if ( itr != TaskHandlers.end( ) )
	{
		if ( itr->second != NULL )
		{
			TFServerTaskHandler & handler=*( itr->second );
			handler ( msg , channel );
		}
	}
}

//Add task handler;
bool TFServerTaskDispatcher::AddHandler(long sig,TFServerTaskHandler* handler)
{
    if( sig < 0 ){
        return false;
    }
    std::pair< std::map<long,TFServerTaskHandler*>::iterator,bool> p = 
        TaskHandlers.insert( std::pair<long ,TFServerTaskHandler*> ( sig , handler ) ) ;
    if( p.second && p.first!=TaskHandlers.end() ){
        return true;
    }else{
        return false;
    }
}

//Remove task handler;
bool TFServerTaskDispatcher::RemoveHandler(long sig)
{
    if( sig < 0 ) {
        return false;
    }
	std::map<long, TFServerTaskHandler*>::iterator itr=TaskHandlers.find(sig);
	if(itr!=TaskHandlers.end())
	{
		TaskHandlers.erase(itr);
                return true;
	}
        return false;
}

TFServerTaskHandler* TFServerTaskDispatcher::GetHandler( long sig ){
    if( sig < 0 ) {
        return false;
    }
    TFServerTaskHandler *ret=NULL;
    std::map<long, TFServerTaskHandler*>::iterator itr=TaskHandlers.find(sig);
    if( itr!=TaskHandlers.end() ){
        ret=itr->second;
    }
    return ret;
}

//=================================================================
//Predefined task handler
//=================================================================
//On Add tag;
void TFSTaskOnAddTag::operator ( ) (TFMessage &msg,TFDuplexChannel & channel)
{
        std::string tag=channel.GetString();
        TFStringBuffer& buf=TFBufferManager::GetInstance().GetStringBuffer("TagBuffer");
        buf.Add(tag);
	std::cout<<"Add tag: ";
	std::cout<<tag<<std::endl;
}

//On Add file 
void TFSTaskOnAddFile::operator ( ) ( TFMessage &msg, TFDuplexChannel & channel)
{
	std::string file = channel.GetString();
        TFStringBuffer& buf=TFBufferManager::GetInstance().GetStringBuffer("FileBuffer");
        buf.Add(file);
	std::cout <<"Add File: " <<file <<std::endl;
}

//On link tag to file
void TFSTaskOnLinkTagToFile::operator ( ) ( TFMessage &msg, TFDuplexChannel & channel)
{
	std::string tag = channel.GetString();
	std::string file = channel.GetString();
        TFStringBuffer& tbuf=TFBufferManager::GetInstance().GetStringBuffer("TagBuffer");
        TFStringBuffer& fbuf=TFBufferManager::GetInstance().GetStringBuffer("FileBuffer");
        TFLinkBuffer& lbuf=TFBufferManager::GetInstance().GetLinkBuffer("TagFileLinkBuffer");
        
	std::cout<<"Link tag "<<tag<<"To file "<<file<<std::endl;
}

//Get all tags
void TFSTaskOnGetAllTags::operator ( ) ( TFMessage & msg, TFDuplexChannel & channel)
{
	std::cout<<"Got command: Get All Tags\nHere are the foo tags:\n";
        //TFMessage msg;
	TFMessage m;
	m.ID = TFMSG_GETALLTAGS;
	m.NextSize = 10;
	channel.Put( &m, sizeof(m) );
	std::string tagfoo = "FooTag";
	for(int i=0; i<m.NextSize; ++i)
	{
		std::cout<<tagfoo<<std::endl;
		tagfoo.push_back( ('0'+i) );
		channel.Put( tagfoo );
	}
}

//Get all files
void TFSTaskOnGetAllFiles::operator ( ) ( TFMessage &msg, TFDuplexChannel & channel)
{
	std::cout<<"Got command: Get All Files\nHere are the foo files:\n";
	TFMessage m;
	m.ID = TFMSG_GETALLFILES;
	m.NextSize = 10;
	channel.Put( &m, sizeof(m) );
	std::string filefoo = "FooFile";
	for(int i=0; i<m.NextSize; ++i)
	{
		std::cout<<filefoo<<"\n";
		filefoo.push_back( ('0'+i) );
		channel.Put( filefoo );
	}
}

//TFSTaskOnGetTagOfFile
void TFSTaskOnGetTagsOfFile::operator ( ) ( TFMessage &msg, TFDuplexChannel & channel)
{
	std::string file = channel.GetString();
	std::cout<<"Got Commnand: Get tags of file "<<file<<"\nHere are its tags:\n";
	TFMessage m;
	m.ID=TFMSG_GETTAGSOFFILE;
	m.NextSize = 10;
	channel.Put( &m, sizeof(m) );
	std::string tagfoo=file;
	tagfoo.append("\'s tag");
	for( int i=0; i<m.NextSize; ++i)
	{
		std::cout<<tagfoo<<std::endl;
		tagfoo.push_back( ('0'+i) );
		channel.Put( tagfoo );
	}
}

//TFSTaskOnGetTagOfFile
void TFSTaskOnGetFilesWithTag::operator ( )(TFMessage &msg, TFDuplexChannel &channel)
{
	std::string tag = channel.GetString();
	std::cout<<"Got command: Get files with tag "<<tag<<"\nHere are its files:\n";
	TFMessage m;
	m.ID=TFMSG_GETTAGSOFFILE;
	m.NextSize = 10;
	channel.Put( &m, sizeof(m) );
	std::string filefoo=tag;
	filefoo.append("\'s tag");
	for( int i=0; i<m.NextSize; ++i)
	{
		std::cout<<filefoo<<std::endl;
		filefoo.push_back( ('0'+i) );
		channel.Put( filefoo );
	}

}

//TFSTaskOnTeminateServer
void TFSTaskOnTeminateServer::operator ( )(TFMessage &, TFDuplexChannel &)
{
	std::cout<<"Shuting down TFServer...\nBye!"<<std::endl;
}
